package fr.insta.reverse.uml.dao;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import fr.insta.reverse.uml.bean.User;
import fr.insta.reverse.uml.util.HibernateUtil;

/**
 * DAO for domain model class User.
 * @see fr.insta.reverse.uml.bean.User
 * @author Valera
 */
@Stateless
public class DaoUser implements IDao<User>
{
	private static final Log log = LogFactory.getLog(DaoUser.class);

	@Override
	public User save(User usr)
	{
		log.debug("saving User instance");
		try
		{
			Session session = HibernateUtil.currentSession();
			Transaction tx = session.beginTransaction();

			session.saveOrUpdate(usr);

			tx.commit();
			HibernateUtil.closeSession();
			log.debug("save successful");
			return usr;
		}
		catch (RuntimeException e)
		{
			log.error("save failed", e);
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public boolean remove(User usr)
	{
		log.debug("removing User instance");
		try
		{
			Session session = HibernateUtil.currentSession();
			Transaction tx = session.beginTransaction();

			usr = (User) session.createCriteria(User.class)
					.add(Restrictions.eq("mail", usr.getMail()))
					.add(Restrictions.eq("password", usr.getPassword()))
					.uniqueResult();

			session.delete(usr);

			tx.commit();
			HibernateUtil.closeSession();
			log.debug("remove successful");
			return true;
		}
		catch (RuntimeException e)
		{
			log.error("remove failed", e);
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public User findById(int id)
	{
		log.debug("getting User instance with id: " + id);
		try
		{
			Session session = HibernateUtil.currentSession();

			User instance = (User) session.createCriteria(User.class)
					.add(Restrictions.eq("id", id))
					.uniqueResult();

			HibernateUtil.closeSession();
			log.debug("get successful");
			return instance;
		}
		catch (RuntimeException re)
		{
			log.error("get failed", re);
			re.printStackTrace();
		}
		return null;
	}

	public User getByUserAndPass(User usr)
	{
		log.debug("getting User instance with mail : " + usr.getMail() + " and password");
		try
		{
			Session session = HibernateUtil.currentSession();

			usr = (User) session.createCriteria(User.class)
					.add(Restrictions.eq("mail", usr.getMail()))
					.add(Restrictions.eq("password", usr.getPassword()))
					.uniqueResult();

			HibernateUtil.closeSession();
			log.debug("get successful");
			return usr;
		}
		catch (RuntimeException re)
		{
			log.error("get failed", re);
			re.printStackTrace();
		}
		return null;
	}

	public User getByMail(User usr)
	{
		log.debug("getting User instance with mail : " + usr.getMail());
		try
		{
			Session session = HibernateUtil.currentSession();

			usr = (User) session.createCriteria(User.class)
					.add(Restrictions.eq("mail", usr.getMail()))
					.uniqueResult();

			HibernateUtil.closeSession();
			log.debug("get successful");
			return usr;
		}
		catch (RuntimeException re)
		{
			log.error("get failed", re);
			re.printStackTrace();
		}
		return null;
	}

	@Override
	public List<User> getAll()
	{
		log.debug("getting all Users");
		List<User> listusers = new ArrayList<User>();
		try
		{
			Session session = HibernateUtil.currentSession();

			listusers = (List<User>) session.createCriteria(User.class).list();

			HibernateUtil.closeSession();
			log.debug("get successful");
			return listusers;
		}
		catch (RuntimeException re)
		{
			log.error("get failed", re);
			re.printStackTrace();
		}
		return null;
	}

	@Override
	public boolean deleteAll()
	{
		log.debug("deleting all Users");
		try
		{
			Session session = HibernateUtil.currentSession();
			Transaction tx = session.beginTransaction();

			session.createQuery("delete from User").executeUpdate();

			tx.commit();
			HibernateUtil.closeSession();
			log.debug("delete successful");
			return true;
		}
		catch (RuntimeException re)
		{
			log.error("delete failed", re);
			re.printStackTrace();
		}
		return false;
	}
}
